home *** CD-ROM | disk | FTP | other *** search
-
- Title 'Wolfware Sample Program', 'Resident Time Display'
-
- ;===============================================;
- ; Resident Time Display Version 1.10 ;
- ; ;
- ; A RAM resident utility which, if active, ;
- ; constantly displays the time in the the ;
- ; upper right corner. Once the utility is ;
- ; installed, the time is activated or ;
- ; deactivated with Alt-1 (hold down the Alt ;
- ; key and type 1 on the numeric keypad, then ;
- ; release the Alt key). The program is ;
- ; initially non-activated when first ;
- ; installed. Once assembled, to install, just ;
- ; type: ;
- ; ;
- ; RTIME ;
- ; ;
- ; The time is updated about three times a ;
- ; second, in the backround of whatever program ;
- ; is presently being executed. The time ;
- ; display overwrites whatever is on the screen ;
- ; at that location. The display can only be ;
- ; activated or deactivated when the foreground ;
- ; program does keyboard I/O via interrupt 16H. ;
- ; This utility uses about 1065 bytes of ;
- ; memory. ;
- ; ;
- ; For simplicity, the program assumes that ;
- ; there are 65535 ticks in an hour, though ;
- ; there are actually 65543. This means that ;
- ; the displayed time is 8 ticks fast for each ;
- ; hour past midnight. The most it is off ;
- ; occurs just before midnight, when it is ;
- ; 8 * 23 = 184 ticks, or about 10 seconds fast. ;
- ; As result of this the time actually runs to ;
- ; about 24:00:10 before switching to 00:00:00. ;
- ; ;
- ; This program may not be compatible with ;
- ; other RAM resident type programs. ;
- ;===============================================;
-
- Proc Far
- Jmp Install ;skip to installation routine
-
- ;===============================================;
- ; Equates ;
- ;===============================================;
-
- True Equ -1 ;true flag
- False Equ 0 ;false flag
-
- ;----- display location, location of first character of 8 byte string
-
- Row Equ 1 ;row, 1 to 25
- Column Equ 73 ;column, 1 to 80
-
- ;----- execution parameters
-
- Key Equ 0001h ;int 16H key code to activate, Alt-1
- Attribute Equ 70h ;display attribute, reverse video
- Count_Set Equ 6 ;wait count, updated 18.2/COUNT_SET = 3/sec
-
- ;----- BIOS data, at segment 0
-
- Equip_Flag Equ 0410h ;equipment word
- Screen_Col Equ 044ah ;CRT columns
-
- ;----- interrupt location, at segement 0
-
- Keyboard Equ 58h ;keyboard fetch, interrupt 16
- Timer_Tick Equ 70h ;timer tick vector location, interrupt 1C
-
- ;----- clock information
-
- Timer_Low Equ 046ch ;low word of timer, at segment 0
- Timer_High Equ 046eh ;high word of timer, at segment 0
-
- Counts_Sec Equ 18 ;counts in second
- Counts_Min Equ 1092 ;counts in minute
- Counts_Hor Equ 0ffffh ;counts in hour
-
- ;----- local stack size, stack just has to handle
- ;----- local routines and any hardware interrupts
-
- Stack Equ 20 + 20 ;size
-
- ;===============================================;
- ; Int16 ;
- ; Alternate interrupt 16H (keyboard I/O) to ;
- ; handle normal function calls while ;
- ; intercepting display activation/deactivation ;
- ; commands. Check for command only if read key ;
- ; or get keyboard status (functions 0 and 1). ;
- ;===============================================;
-
- Int16 Proc Far
- Sti ;interrupts on
- Pushf ;save entry flags
-
- ;----- read next key
-
- Or Ah, Ah ;check if read key
- Jnz Nonkey ;jump if not
-
- I16get
- Seg Cs ;code segment
- Call Old_Int16 ;keyboard interrupt
- Cmp Ax, Key ;check scan code
- Je Subkey ;jump if activate key
- Iret
-
- ;----- activation key on read
-
- Subkey
- Call Toggle_Act ;toggle present setting
- Sub Sp, 2 ;simulate flags for interrupt call
- Sub Ah, Ah ;read next key function
- Jmps I16get ;try again
-
- ;----- keyboard status
-
- Nonkey
- Cmp Ah, 1 ;check if keyboard status
- Jne Nonstat ;jump if not
- Popf ;restore entry flags
-
- Pushf ;flags for interrupt call
- Seg Cs ;code segment
- Call Old_Int16 ;keyboard interrupt
- Pushf
- Jnz I16chksk ;jump if key in buffer
-
- Popf
- Ret 2 ;throw away flags in stack on return
-
- I16chksk
- Cmp Ax, Key ;check scan code
- Je I16fact ;jump if activate key
-
- Popf
- Ret 2 ;throw away flags in stack on return
-
- ;----- activation key on status
-
- I16fact
- Sub Ah, Ah ;get key function
- Sub Sp, 2 ;simulate flags for interrupt call
- Seg Cs ;code segment
- Call Old_Int16 ;keyboard interrupt, get key
-
- Call Toggle_Act ;toggle present setting
-
- Mov Ah, 1 ;status function
- Jmps Nonkey ;try again, flags still on stack
-
- ;----- keyboard shift status or unknown function
-
- Nonstat
- Seg Cs ;code segment
- Call Old_Int16 ;keyboard interrupt, (flags on stack)
- Iret
- Endp ;Int16
-
- ;===============================================;
- ; Toggle_Act ;
- ; Toggle active setting and reset screen info. ;
- ; Clears time display (sets to dashes). ;
- ;===============================================;
-
- Toggle_Act Proc Near
- Seg Cs
- Cmp Activated, True ;check if on
- Je Actoff ;jump if so, turn off
-
- ;----- activate
-
- Seg Cs
- Mov Activated, True ;activate
- Seg Cs
- Mov Counter, Count_Set ;reset counter
- Jmps Screenres
-
- ;----- deactivate
-
- Actoff Seg Cs
- Mov Activated, False ;activate off
-
- ;----- reset screen information and clear display
-
- ;----- switch to local stack
-
- Screenres Seg Cs
- Mov Stack_Seg, Ss ;save stack segment
-
- Seg Cs
- Mov Temp, Cs
- Seg Cs
- Mov Ss, Temp ;new stack segment
-
- Seg Cs
- Mov Stack_Off, Sp ;save stack pointer
-
- Seg Cs
- Mov Sp, Local_Stk ;new stack
-
- ;----- save all registers
-
- Push Ax
- Push Bx
- Push Cx
- Push Dx
- Push Di
- Push Si
- Push Ds
- Push Es
-
- Cld ;forward direction
-
- ;----- set screen information
-
- Sub Ax, Ax
- Mov Ds, Ax ;segement 0
-
- Mov Bx, [Screen_Col] ;screen columns
- Mov Ax, 0b800h ;graphics segment
-
- Mov Dx, [Equip_Flag] ;get equipment flag
- And Dx, 30h ;mask CRT bits
- Cmp Dx, 30h ;check if BW card
- Jne Notbw ;jump if not
-
- Mov Ax, 0b000h ;BW segement
-
- Notbw Mov Dx, Cs
- Mov Ds, Dx
- Mov Es, Dx ;set data segment registers
-
- Mov Screen_Seg, Ax ;save segment
-
- ;----- calculate screen offset
-
- Mov Ax, Bx
- Sub Dx, Dx
- Mul Ax, Time_Row ;row offset
- Add Ax, Time_Col ;add for columns
- Shl Ax ;times two, account for attribute bytes
- Mov Screen_Off, Ax ;save
-
- ;----- clear time display (set numbers to dashes)
-
- Mov Ax, 2d2dh ;dashes to clear time and date
-
- Cli ;interrupts off while display
- Mov Di, Offset Tdisplay;dislay line
- Stosw ;hours
- Inc Di
- Stosw ;minutes
- Inc Di
- Stosw ;seconds
-
- Call Display ;display new string
- Sti ;interrupts back on
-
- ;----- restore registers
-
- Pop Es
- Pop Ds
- Pop Si
- Pop Di
- Pop Dx
- Pop Cx
- Pop Bx
- Pop Ax
-
- ;----- restore stack
-
- Seg Cs
- Mov Sp, Stack_Off ;stack pointer
-
- Seg Cs
- Mov Ss, Stack_Seg ;stack segment
- Ret
- Endp ;Toggle_Act
-
- ;===============================================;
- ; Int1c ;
- ; Alternate interrupt 1CH (timer tick). ;
- ; Executed every timer tick (about 18.2 times ;
- ; a second). ;
- ; ;
- ; One out of COUNT_SET cycles the time is ;
- ; displayed to its predetermined location, so ;
- ; the time is actually updated 18.2/COUNT_SET ;
- ; times per second. ;
- ; ;
- ; Each interrupt calls the original timer tick ;
- ; interrupt for the benefit of any other ;
- ; routines that were using it. ;
- ;===============================================;
-
- Int1c Proc Near
- Cli ;interrupts off
-
- ;----- check if activated
-
- Seg Cs
- Cmp Activated, True ;check if activated
- Je Redischk ;jump if so
-
- Exit Pushf ;flags for interrupt call
- Seg Cs
- Call Old_Int1c ;call original interrupt
- Iret
-
- Redischk Seg Cs
- Dec Counter ;decrement counter
- Jnz Exit ;jump if not zero
-
- ;----- redisplay time
-
- ;----- switch to internal stack
-
- Seg Cs
- Mov Activated, False ;deactivate
-
- Seg Cs
- Mov Stack_Seg, Ss ;save stack segment
-
- Seg Cs
- Mov Temp, Cs
- Seg Cs
- Mov Ss, Temp ;new stack segment
-
- Seg Cs
- Mov Stack_Off, Sp ;save stack pointer
-
- Seg Cs
- Mov Sp, Local_Stk ;new stack
-
- ;----- save all registers
-
- Push Ax
- Push Bx
- Push Cx
- Push Dx
- Push Di
- Push Si
- Push Ds
- Push Es
-
- Cld ;forward direction
-
- ;----- get time
-
- Sub Ax, Ax
- Mov Ds, Ax ;segment 0
-
- Mov Dx,[Timer_High] ;timer high
- Mov Ax,[Timer_Low] ;timer low
-
- ;----- set time
-
- Mov Bx, Cs
- Mov Ds, Bx
- Mov Es, Bx ;set segment registers
-
- Mov Counter, Count_Set ;reset counter
-
- Mov Di, Offset Tdisplay ;start of time display string
-
- Mov Bx, Counts_Hor ;counts/hour
- Div Ax, Bx ;divide
- Call Number_Con ;convert to ASCII and store
- Inc Di ;skip colon
-
- Mov Ax, Dx ;remainder is new dividend
- Sub Dx, Dx
- Mov Bx, Counts_Min ;counts/minute
- Div Ax, Bx ;divide
- Call Number_Con ;convert to ASCII and store
- Inc Di ;skip colon
-
- Mov Ax, Dx ;remainder is new dividend
- Sub Dx, Dx
- Mov Bx, Counts_Sec ;counts/second
- Div Ax, Bx ;divide
- Call Number_Con ;convert to ASCII and store
-
- Call Display ;display string to screen
-
- ;----- restore registers
-
- Pop Es
- Pop Ds
- Pop Si
- Pop Di
- Pop Dx
- Pop Cx
- Pop Bx
- Pop Ax
-
- ;----- restore stack
-
- Seg Cs
- Mov Sp, Stack_Off ;restore stack pointer
-
- Seg Cs
- Mov Ss, Stack_Seg ;restore stack segment
-
- Seg Cs
- Mov Activated, True ;reactivate
- Jmp Exit ;exit routine
- Endp ;Int1c
-
- ;===============================================;
- ; Number_Con ;
- ; Convert number in AL to two digit ASCII ;
- ; string and store result to DI. Number must ;
- ; be in range 0 to 99. DI returns pointing to ;
- ; byte after new string. ;
- ;===============================================;
-
- Number_Con Proc Near
- Shl Al
- Sub Ah, Ah ;AX gets relative offset
- Add Ax, Offset Numbers ;absolute offset
- Mov Si, Ax
- Movsw ;move word (two byte digits)
- Ret
-
- ;----- data, 00 to 99
-
- Numbers Label Byte
- Db '00010203040506070809'
- Db '10111213141516171819'
- Db '20212223242526272829'
- Db '30313233343536373839'
- Db '40414243444546474849'
- Db '50515253545556575859'
- Db '60616263646566676869'
- Db '70717273747576777879'
- Db '80818283848586878889'
- Db '90919293949596979899'
- Endp ;Number_Con
-
- ;===============================================;
- ; Display ;
- ; Display the time string to the screen by ;
- ; writing it directly to the screen buffer. ;
- ;===============================================;
-
- Display Proc Near
- Mov Ah, Attribute ;display attribute
- Mov Cx, Offset Tdisplay_End - Offset Tdisplay ;length
- Mov Di, Screen_Off ;offset into screen
- Mov Si, Offset Tdisplay ;start of time string
- Mov Es, Screen_Seg ;segment of screen
-
- ;----- move string to screen buffer
-
- Disloop Lodsb ;load character
- Stosw ;store character and attribute
- Loop Disloop ;loop CX times
- Ret
- Endp ;Display
-
- ;===============================================;
- ; Data ;
- ;===============================================;
-
- Activated Db False ;activation status, initially off
- Counter Db ? ;execution counter, set when activated
-
- Time_Row Dw Row - 1 ;display row
- Time_Col Dw Column - 1 ;display column
-
- Stack_Off Dw ? ;storage for stack offset
- Stack_Seg Dw ? ;storage for stack segment
- Local_Stk Dw Offset End + Stack ;local stack top
-
- Screen_Off Dw ? ;screen offset
- Screen_Seg Dw ? ;screen segment
-
- Temp Dw ? ;temporary storage
-
- ;----- display string
-
- Tdisplay Label Byte ;start of string
- Db '--:--:--'
- Tdisplay_End Label Byte ;end of string (to calculate length)
-
- ;----- original interrupts
-
- Old_Int16 Label Dword
- Dw ? ;offset
- Dw ? ;segment
-
- Old_Int1c Label Dword
- Dw ? ;offset
- Dw ? ;segment
-
- End Label Byte ;end of code and data, start of stack space
-
- ;===============================================;
- ; Install ;
- ; Install the alternate interrupts. ;
- ;===============================================;
-
- Install Proc Near
-
- ;----- install new interrupt vectors
-
- Mov Ax, Offset Int16 ;keyboard offset
- Mov Bx, Cs ;present segement
- Mov Cx, Offset Int1c ;timer offset
- Mov Dx, Cs ;present segement
-
- ;----- get and save old interrupts
-
- Mov Ax, 3516h ;function and interrupt 16h
- Int 21h ;execute
- Mov Word Old_Int16, Bx ;offset
- Mov Word Old_Int16+2, Es ;segment
-
- Mov Ax, 351ch ;function and interrupt 1ch
- Int 21h ;execute
- Mov Word Old_Int1c, Bx ;offset
- Mov Word Old_Int1c+2, Es ;segment
-
- ;----- set new interrupts
-
- Mov Ax, 2516h ;function and interrupt 16h
- Mov Dx, Offset Int16 ;keyboard offset
- Int 21h ;execute
-
- Mov Ax, 251ch ;function and interrupt 1ch
- Mov Dx, Offset Int1c ;timer offset
- Int 21h ;execute (and it's off!)
-
- ;----- display message
-
- Mov Dx, Offset Installm ;message location
- Mov Ah, 9 ;print string function
- Int 21h ;execute
-
- ;----- finish up
-
- Mov Dx, Local_Stk ;end of interrupt, top of local stack
- Mov Cl, 4
- Shr Dx, Cl ;paragraph form
- Inc Dx ;allow for fraction of paragraph
-
- Mov Ax, 3100h ;exit function (stay resident)
- Int 21h ;execute
-
- ;----- message
-
- Installm Db 10
- Db '/-------------------------------------------\', 13, 10
- Db '| Resident time display utility installed |', 13, 10
- Db '|----------------- Ver 1.10 ----------------|', 13, 10
- Db '| press ALT-1 to activate/deactivate |', 13, 10
- Db '\-------------------------------------------/', 13, 10,'$'
- Endp ;Install
-
- Endp ;main program
-
-